package com.se.db;

import com.se.common.Message;
import com.se.common.MessageType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.se.common.Constant.GET_SQL_CONNECTION_FAILED;

public class DbMessage {
    private static volatile DbMessage instance;
    private static final Logger logger = LoggerFactory.getLogger(DbMessage.class);

    private DbMessage() {
    }

    public static DbMessage getInstance() {
        if(instance == null) {
            synchronized (DbMessage.class) {
                if(instance == null) {
                    instance = new DbMessage();
                }
            }
        }
        return instance;
    }

    public void add(Message message) throws SQLException {
        Connection conn = DbUtils.getConnection();
        PreparedStatement ps = null;
        String sql = "INSERT INTO message(sendUser,receiveUser,content,sendTime,type) VALUES(?,?,?,?,?)";

        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }

        ps = conn.prepareStatement(sql);
        ps.setString(1,message.getSendUser());
        ps.setString(2,message.getReceiveUser());
        ps.setString(3,message.getContent());
        ps.setString(4,message.getSendTime());
        ps.setString(5,message.getMsgType());
        ps.executeUpdate();
        DbUtils.close(ps, conn);
    }

    public List<Message> getBySendUserAndReceiveUser(String sendUser, String receiveUser) throws SQLException {
        String sql = "SELECT sendUser,receiveUser,content,sendTime,type " +
                "FROM message WHERE sendUser = ? AND receiveUser = ?";
        List<Message> messages = new ArrayList<>();
        Connection conn = DbUtils.getConnection();
        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }
        try(PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setString(1, sendUser);
            ps.setString(2, receiveUser);
            try(ResultSet rs = ps.executeQuery()) {
                while(rs.next()) {
                    messages.add(mapMessage(rs));
                }
            }
        }
        DbUtils.close(conn);
        logger.info("从数据库获取消息列表，长度为: {}", messages.size());
        return messages;
    }

    public List<Message> getBySendUser(String sendUser) throws SQLException {
        String sql = "SELECT sendUser,receiveUser,content,sendTime,type FROM message WHERE sendUser = ?";
        List<Message> messages = new ArrayList<>();
        Connection conn = DbUtils.getConnection();
        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }

        try(PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setString(1, sendUser);

            try(ResultSet rs = ps.executeQuery()) {
                while(rs.next()) {
                    messages.add(mapMessage(rs));
                }
            }
        }
        DbUtils.close(conn);
        return messages;
    }

    public List<Message> getByReceiveUser(String receiveUser) throws SQLException {
        String sql = "SELECT sendUser,receiveUser,content,sendTime,type FROM message WHERE receiveUser = ?";
        List<Message> messages = new ArrayList<>();
        Connection conn = DbUtils.getConnection();
        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }

        try(PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setString(1, receiveUser);

            try(ResultSet rs = ps.executeQuery()) {
                while(rs.next()) {
                    messages.add(mapMessage(rs));
                }
            }
        }
        DbUtils.close(conn);
        return messages;
    }

    public void deleteAIExplainMessage(String username) throws SQLException {
        String sql = "DELETE FROM message WHERE receiveUser=? and type=?";
        Connection conn = DbUtils.getConnection();

        if(conn == null) {
            throw new SQLException(GET_SQL_CONNECTION_FAILED);
        }

        try(PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setString(1, username);
            ps.setString(2, MessageType.MESSAGE_SENTENCE_EXPLAIN);
            ps.executeUpdate();
        }

        DbUtils.close(conn);
        logger.info("删除了用户 {} 的所有AI解释消息", username);
    }

    private Message mapMessage(ResultSet rs) throws SQLException {
        Message message = new Message();
        message.setSendUser(rs.getString("sendUser"));
        message.setReceiveUser(rs.getString("receiveUser"));
        message.setContent(rs.getString("content"));
        message.setSendTime(rs.getObject("sendTime", LocalDateTime.class)
                .format(DbUtils.formatter));
        message.setMsgType(rs.getString("type"));
        return message;
    }
}
